using System;
using System.Text;
using Mina.Core.Buffer;
using Mina.Core.Session;
using Mina.Filter.Codec;

namespace Com.FirstSolver.Splash;

public class FaceReaderEncoderAdapter : IProtocolEncoder
{
	private static readonly AttributeKey KEY_ENCRYPTOR = new AttributeKey(typeof(FaceReaderEncoderAdapter), "Encryptor");

	public void Encode(IoSession session, object message, IProtocolEncoderOutput output)
	{
		if (!string.IsNullOrEmpty(message as string))
		{
			byte[] Source = Encoding.UTF8.GetBytes((string)message);
			if (session.GetAttribute(KEY_ENCRYPTOR) is SM4 Encryptor)
			{
				Source = Encryptor.TransformFinalBlock(Source, 0, Source.Length);
			}
			IoBuffer Buffer = IoBuffer.Allocate(Source.Length + 4);
			Buffer.Put(Utils.GetBytes(Source.Length, ByteOrder.BIG_ENDIAN));
			Buffer.Put(Source);
			Buffer.Flip();
			output.Write(Buffer);
		}
	}

	public void Dispose(IoSession session)
	{
		((IDisposable)session.GetAttribute(KEY_ENCRYPTOR))?.Dispose();
		session.RemoveAttribute(KEY_ENCRYPTOR);
	}

	public static void SetSecretKey(IoSession session, byte[] secretKey, int mode)
	{
		if (session.GetAttribute(KEY_ENCRYPTOR) is SM4 Encryptor)
		{
			Encryptor.Dispose();
			session.RemoveAttribute(KEY_ENCRYPTOR);
		}
		if (secretKey != null)
		{
			SM4 Encryptor2 = new SM4(CipherDirection.Encryption, CipherMode.OFB);
			byte[] DerivedVector = ((mode != 0 || secretKey.Length != 32) ? SM3.KDF(secretKey, 32) : secretKey);
			byte[] Key = new byte[16];
			Array.Copy(DerivedVector, 0, Key, 0, 16);
			byte[] IV = new byte[16];
			Array.Copy(DerivedVector, 16, IV, 0, 16);
			Encryptor2.Initialize(Key, IV);
			session.SetAttribute(KEY_ENCRYPTOR, Encryptor2);
		}
	}
}
